<!-- HTML header for doxygen 1.8.3.1-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<title>AngelScript: Funcdefs and script callback functions</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="test/javascript" src="touch.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
  $(window).load(resizeHeight);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">AngelScript
   </div>
  </td>
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('doc_callbacks.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark">&#160;</span>Pages</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">Funcdefs and script callback functions </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><a class="el" href="doc_global_funcdef.html">Funcdefs</a> are used to define a function signature for callbacks. This funcdef is then used to declare variables or function parameters that can hold handles to functions of matching signature.</p>
<p>The application can also <a class="el" href="classas_i_script_engine.html#a03c1a2cc23ae4b742c927f3472a1a4f7">register funcdefs</a> as part of the application interface if the intention is for the script to set callbacks that will be called from the application. Once this is done, the application can receive the function handles as an <a class="el" href="classas_i_script_function.html" title="The interface for a script function description.">asIScriptFunction</a> pointer which can then be <a class="el" href="doc_call_script_func.html">executed</a> normally.</p>
<h1><a class="anchor" id="doc_callbacks_example"></a>
An example</h1>
<p>Let's say the application needs to allow the script to set a callback that will then be called at some event. To do this the application would first register the funcdef that defines the signature of the callback. Then it needs to register the function that will be used to set the callback from the script.</p>
<div class="fragment"><div class="line"><span class="comment">// Register a simple funcdef for the callback</span></div>
<div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#a03c1a2cc23ae4b742c927f3472a1a4f7" title="Registers a function definition.">RegisterFuncdef</a>(<span class="stringliteral">&quot;void CallbackFunc()&quot;</span>); </div>
<div class="line"></div>
<div class="line"><span class="comment">// Register a function for setting the callback</span></div>
<div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#a2f84b9b51733f22c68b8448b02c2f1c7" title="Registers a global function.">RegisterGlobalFunction</a>(<span class="stringliteral">&quot;void SetCallback(CallbackFunc @cb)&quot;</span>, <a class="code" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae" title="Returns an asSFuncPtr representing the function specified by the name.">asFUNCTION</a>(SetCallback), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4" title="A cdecl function.">asCALL_CDECL</a>);  </div>
</div><!-- fragment --><p>With this interface, the script would be able to inform the callback like this:</p>
<pre>
  void main()
  {
    // Tell the application what script function to call
    SetCallback(MyCallback);
  }</pre><pre>  // The signature matches the registered CallbackFunc funcdef
  void MyCallback()
  {
    ...
  }
</pre><p>The implementation for the SetCallback function might look something like this.</p>
<div class="fragment"><div class="line"><span class="comment">// The callback is a script function.</span></div>
<div class="line"><span class="comment">// Don&#39;t forget to release this before cleaning up the engine.</span></div>
<div class="line">asIScriptFunction *callback = 0;</div>
<div class="line"></div>
<div class="line"><span class="keywordtype">void</span> SetCallback(asIScriptFunction *cb)</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// Release the previous callback, if any</span></div>
<div class="line">  <span class="keywordflow">if</span>( callback )</div>
<div class="line">    callback-&gt;<a class="code" href="classas_i_script_function.html#a0a98f1f7f91574a11d7d8c5062bdcdee" title="Decrease reference counter.">Release</a>();</div>
<div class="line"></div>
<div class="line">  <span class="comment">// Store the received handle for later use</span></div>
<div class="line">  callback = cb;</div>
<div class="line"></div>
<div class="line">  <span class="comment">// Do not release the received script function </span></div>
<div class="line">  <span class="comment">// until it won&#39;t be used any more</span></div>
<div class="line">}</div>
</div><!-- fragment --><p>To call the actual callback when it is time, the application uses the script context just like for any other <a class="el" href="doc_call_script_func.html">call to a script function</a>.</p>
<h1><a class="anchor" id="doc_callbacks_delegate"></a>
Delegates</h1>
<p>Of course, callbacks can be used with <a class="el" href="doc_datatypes_funcptr.html">delegates</a> as well. Delegates are special function objects that holds a reference to an object and the method it should call on it. If this is exactly how the application should treat them, then the above example will work exactly the same and the application never needs to worry about whether the callback is actually a global function or a delegate object.</p>
<p>Sometimes however, it may be beneficial to break up the delegate, and have the application store the actual object and method separately, for example if the application should use a <a class="el" href="doc_adv_weakref.html">weak reference</a> to avoid keeping the object alive longer than desired. The following shows how to retrieve the internals of the delegate:</p>
<div class="fragment"><div class="line"><span class="comment">// The callback, and accompanying object, if the callback is a class method</span></div>
<div class="line">asIScriptFunction *callback           = 0;</div>
<div class="line"><span class="keywordtype">void</span>              *callbackObject     = 0;</div>
<div class="line"><a class="code" href="classas_i_type_info.html" title="The interface for describing types This interface is used to describe the types in the script engine...">asITypeInfo</a>       *callbackObjectType = 0;</div>
<div class="line"></div>
<div class="line"><span class="keywordtype">void</span> SetCallback(asIScriptFunction *cb)</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// Release the previous callback, if any</span></div>
<div class="line">  <span class="keywordflow">if</span>( callback )</div>
<div class="line">    callback-&gt;<a class="code" href="classas_i_script_function.html#a0a98f1f7f91574a11d7d8c5062bdcdee" title="Decrease reference counter.">Release</a>();</div>
<div class="line">  <span class="keywordflow">if</span>( callbackObject )</div>
<div class="line">    engine-&gt;<a class="code" href="classas_i_script_engine.html#a82873d3769ded547894a7c3d52c220fd" title="Release the object pointer.">ReleaseScriptObject</a>(callbackObject, callbackObjectType);</div>
<div class="line">  callback           = 0;</div>
<div class="line">  callbackObject     = 0;</div>
<div class="line">  callbackObjectType = 0;</div>
<div class="line">  </div>
<div class="line">  <span class="keywordflow">if</span>( cb &amp;&amp; cb-&gt;<a class="code" href="classas_i_script_function.html#aa4d06c7d590e7eb4df280a8224f4499c" title="Returns the type of the function.">GetFuncType</a>() == <a class="code" href="angelscript_8h.html#a06fb2a1ebf5d007e0d542abced1b648fa02773b148f9c6fb3ed5d945a940f302a" title="A function delegate.">asFUNC_DELEGATE</a> )</div>
<div class="line">  {</div>
<div class="line">    callbackObject     = cb-&gt;<a class="code" href="classas_i_script_function.html#ae1786c3f4341dc3bfcaacc3cb8900a57" title="Returns the object for the delegate.">GetDelegateObject</a>();</div>
<div class="line">    callbackObjectType = cb-&gt;<a class="code" href="classas_i_script_function.html#ad79461f80fcffd513b43564d75cc5360" title="Returns the type of the delegated object.">GetDelegateObjectType</a>();</div>
<div class="line">    callback           = cb-&gt;<a class="code" href="classas_i_script_function.html#aa28f4e68da8abb770d7f725375bcd2bb" title="Returns the function for the delegate.">GetDelegateFunction</a>();</div>
<div class="line"></div>
<div class="line">    <span class="comment">// Hold on to the object and method</span></div>
<div class="line">    engine-&gt;<a class="code" href="classas_i_script_engine.html#ade1d309876c876c733d437a53e708c28" title="Increase the reference counter for the script object.">AddRefScriptObject</a>(callbackObject, callbackObjectType);</div>
<div class="line">    callback-&gt;<a class="code" href="classas_i_script_function.html#a0a00f9581e7ece5f2a536d0e22c10d0c" title="Increases the reference counter.">AddRef</a>();</div>
<div class="line"></div>
<div class="line">    <span class="comment">// Release the delegate, since it won&#39;t be used anymore</span></div>
<div class="line">    cb-&gt;<a class="code" href="classas_i_script_function.html#a0a98f1f7f91574a11d7d8c5062bdcdee" title="Decrease reference counter.">Release</a>();</div>
<div class="line">  }</div>
<div class="line">  <span class="keywordflow">else</span></div>
<div class="line">  {</div>
<div class="line">    <span class="comment">// Store the received handle for later use</span></div>
<div class="line">    callback = cb;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// Do not release the received script function </span></div>
<div class="line">    <span class="comment">// until it won&#39;t be used any more</span></div>
<div class="line">  }</div>
<div class="line">}</div>
</div><!-- fragment --> </div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Sun Dec 18 2016 12:35:28 for AngelScript by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.3.1 </li>
  </ul>
</div>
</body>
</html>
